<!-- 页面模板 英雄页面主模板 包含导航栏、英雄展示区域、技能武器信息、加载状态等 -->
<template>
  <!-- 英雄页面 根容器 包含所有页面内容 -->
  <div class="hero-page">
    <!-- 顶部导航栏 导航组件 监听导航事件、登录注册事件、登出事件 -->
    <TopNavbar     
      @navigate="handleNavigation" 
      @show-login="showLogin"
      @show-register="showRegister"
      @logout="handleLogout"
    />
    
    <!-- 英雄列表/三栏布局 主内容区域 条件渲染：非加载状态时显示 -->
    <div class="valkyrie-layout" v-if="!loading">
      <!-- 左：英雄名字标题和竖排英雄名字列表 左侧边栏 显示英雄标题和英雄列表 -->
      <aside class="valkyrie-left">
        <!-- 英雄标题 显示当前选中英雄的称谓或名称 条件渲染：有选中英雄时显示 -->
        <h2 class="codename" v-if="selectedHero">{{ selectedHero.title || selectedHero.heroName }}</h2>
        <!-- 英雄名称列表 无序列表 显示所有英雄名称 -->
        <ul class="name-list">
          <!-- 英雄名称项 列表项 遍历英雄数组 动态绑定激活状态 点击切换选中英雄 -->
          <li
            v-for="hero in heroes"
            :key="hero.id"
            class="name-item"
            :class="{ active: selectedHero && selectedHero.id === hero.id }"
            @click="selectHero(hero)"
          >
            <!-- 装饰点 小圆点装饰 -->
            <span class="dot"></span>
            <!-- 英雄名称文本 显示英雄名称 -->
            <span class="name-text">{{ hero.heroName || hero.name }}</span>
          </li>
        </ul>
      </aside>

      <!-- 中：大图展示 中央主展示区域 显示英雄大图 -->
      <main class="valkyrie-center">
        <!-- 英雄插图容器 条件渲染：有选中英雄时显示 -->
        <div class="hero-illus" v-if="selectedHero">
          <!-- 英雄大图 动态绑定图片源和alt属性 -->
          <img :src="selectedHero.largeIconUrl || selectedHero.imageUrl || defaultHeroImage" :alt="selectedHero.heroName || selectedHero.name" />
        </div>
        <!-- 占位符容器 条件渲染：无选中英雄时显示 -->
        <div v-else class="hero-illus placeholder"></div>
      </main>

      <!-- 右：属性与缩略图、视频海报 右侧边栏 显示英雄详细信息 条件渲染：有选中英雄时显示 -->
      <aside class="valkyrie-right" v-if="selectedHero">
        <!-- 元信息头部 预留头部区域 -->
        <div class="meta-header">
         
        </div>

        <!-- 基本属性区 英雄基础信息展示区域 包含姓名、称谓、属性、作战方式、伤害类型、星环分野等信息 -->
        <div class="meta-list">
          <!-- 姓名行 带图标的姓名信息行 包含英雄小头像和姓名 -->
          <div class="meta-row name-with-icon">
            <!-- 标签 姓名标签 -->
            <span class="label">姓名：</span>
            <!-- 姓名图标组 包含头像和姓名的组合 -->
            <div class="name-icon-group">
              <!-- 英雄小头像 动态绑定头像源和alt属性 -->
              <img class="hero-mini-icon" :src="selectedHero.smallIconUrl || selectedHero.avatarUrl || defaultAvatarImage" :alt="selectedHero.heroName || selectedHero.name" />
              <!-- 姓名值 显示英雄姓名 -->
              <span class="value">{{ selectedHero.heroName || selectedHero.name || '-' }}</span>
            </div>
          </div>
          <!-- 双列信息行 称谓和属性信息 -->
          <div class="meta-row-double">
            <!-- 称谓信息项 -->
            <div class="meta-item">
              <!-- 称谓标签 -->
              <span class="label">称谓：</span>
              <!-- 称谓值 显示英雄称谓 -->
              <span class="value">{{ selectedHero.title || '-' }}</span>
            </div>
            <!-- 属性信息项 -->
            <div class="meta-item">
              <!-- 属性标签 -->
              <span class="label">属性：</span>
              <!-- 属性值 显示英雄属性类型 -->
              <span class="value">{{ selectedHero.attributeType || '-' }}</span>
            </div>
          </div>
          <!-- 双列信息行 作战方式和伤害类型信息 -->
          <div class="meta-row-double">
            <!-- 作战方式信息项 -->
            <div class="meta-item">
              <!-- 作战方式标签 -->
              <span class="label">作战方式：</span>
              <!-- 作战方式值 显示武器类型或作战风格 -->
              <span class="value">{{ selectedHero.weaponType || selectedHero.combatStyle || '-' }}</span>
            </div>
            <!-- 伤害类型信息项 -->
            <div class="meta-item">
              <!-- 伤害类型标签 -->
              <span class="label">伤害类型：</span>
              <!-- 伤害类型值 显示伤害类型 -->
              <span class="value">{{ selectedHero.damageType || '-' }}</span>
            </div>
          </div>
          <!-- 星环分野行 单行信息 -->
          <div class="meta-row">
            <!-- 星环分野标签 -->
            <span class="label">星环分野：</span>
            <!-- 星环分野值 显示星环分野信息 -->
            <span class="value">{{ selectedHero.starRingDivision || '-' }}</span>
          </div>
        </div>



        <!-- 背景介绍区域 英雄背景故事展示区域 条件渲染：有选中英雄且有背景描述时显示 -->
        <div class="background-description" v-if="selectedHero && selectedHero.backgroundDescription">
          <!-- 描述头部 包含标题和分隔线 -->
          <div class="description-header">
            <!-- 描述标题 背景介绍标题 -->
            <h3 class="description-title">背景介绍</h3>
            <!-- 描述分隔线 装饰性分隔线 -->
            <div class="description-divider"></div>
          </div>
          <!-- 描述内容 背景故事文本内容 -->
          <div class="description-content">
            <!-- 描述文本 显示英雄背景描述 自动缩进 -->
            <p class="description-text">{{ selectedHero.backgroundDescription }}</p>
          </div>
        </div>




<!-- 
        <div class="thumb-strip">
          <div
            v-for="hero in heroes"
            :key="'mini-' + hero.id"
            class="mini-thumb"
            :class="{ active: selectedHero && selectedHero.id === hero.id }"
            @click="selectHero(hero)"
            @mouseenter="handleThumbEnter(hero)"
            @mouseleave="handleThumbLeave"
          >
            <img :src="hero.smallIconUrl || hero.avatarUrl || defaultAvatarImage" :alt="hero.heroName || hero.name" />
          </div>
        </div> -->
        



        <!-- 技能展示区域 英雄技能信息展示区域 条件渲染：有选中英雄时显示 -->
        <div class="skills-section" v-if="selectedHero">
          <!-- 技能头部 包含技能标题和分隔线 -->
          <div class="skills-header">
            <!-- 技能标题 显示当前英雄的技能标题 优先显示悬停英雄名称 -->
            <h3 class="skills-title">{{ (hoveredHero ? (hoveredHero.heroName || hoveredHero.name) : (selectedHero.heroName || selectedHero.name)) }} 的技能</h3>
            <!-- 技能分隔线 装饰性分隔线 -->
            <div class="skills-divider"></div>
          </div>
          
          <!-- 技能加载状态 条件渲染：技能加载中时显示 -->
          <div v-if="skillsLoading" class="skills-loading">
            <!-- 加载动画 旋转加载图标 -->
            <div class="loading-spinner"></div>
            <!-- 加载提示文本 -->
            <p>加载技能中...</p>
          </div>

          <!-- 技能列表 条件渲染：非加载状态且有技能数据时显示 -->
          <div v-if="!skillsLoading && heroSkills.length > 0" class="skills-list">
            <!-- 技能卡片 遍历技能数组 点击查看技能详情 -->
            <div 
              v-for="skill in heroSkills" 
              :key="skill.skillId" 
              class="skill-card clickable-skill"
              @click="viewSkillDetail(skill)"
            >
              <!-- 技能头部 包含技能名称和详情图标 -->
              <div class="skill-header">
                <!-- 技能名称 显示技能名称 -->
                <h4 class="skill-name">{{ skill.skillName }}</h4>
                <!-- 详情图标 查看详情的图标 -->
                <div class="detail-icon">📋</div>
              </div>
              
              <!-- 技能gif展示 条件渲染：有gif链接时显示 -->
              <div class="skill-gif" v-if="skill.gifUrl">
                <!-- 技能gif图片 动态绑定gif源和alt属性 -->
                <img :src="skill.gifUrl" :alt="skill.skillName + ' gif'" class="skill-gif-image" />
              </div>
              
              <!-- 技能描述 条件渲染：有技能描述时显示 -->
              <div class="skill-description" v-if="skill.skillDescription">
                <!-- 技能描述文本 显示技能描述内容 -->
                <p>{{ skill.skillDescription }}</p>
              </div>
              
              <!-- 技能操作按钮组 包含查看详情和播放视频按钮 -->
              <div class="skill-actions">
                <!-- 查看详情按钮 阻止事件冒泡 点击查看技能详情 -->
                <div class="skill-detail-btn" @click.stop="viewSkillDetail(skill)">
                  <!-- 详情按钮图标 眼睛图标 -->
                  <span class="detail-btn-icon">👁️</span>
                  查看详情
                </div>
                <!-- 播放视频按钮 条件渲染：有视频链接时显示 阻止事件冒泡 点击播放技能视频 -->
                <div class="skill-video-btn" v-if="skill.videoUrl" @click.stop="playSkillVideo(skill)">
                  <!-- 视频按钮图标 播放图标 -->
                  <span class="video-btn-icon">▶</span>
                  播放视频
                </div>
              </div>
            </div>
          </div>
          
          <!-- 无技能提示 条件渲染：非加载状态且无技能数据时显示 -->
          <div v-if="!skillsLoading && heroSkills.length === 0" class="no-skills">
            <!-- 无技能提示文本 -->
            <p>该英雄暂无技能信息</p>
          </div>
        </div>
        



        <!-- 推荐武器区域 英雄推荐武器展示区域 条件渲染：有选中英雄时显示 -->
        <div class="weapons-section" v-if="selectedHero">
          <!-- 武器头部 包含武器标题和分隔线 -->
          <div class="weapons-header">
            <!-- 武器标题 推荐武器标题 -->
            <h3 class="weapons-title">推荐武器</h3>
            <!-- 武器分隔线 装饰性分隔线 -->
            <div class="weapons-divider"></div>
          </div>
          
          <!-- 武器加载状态 条件渲染：武器加载中时显示 -->
          <div v-if="weaponsLoading" class="weapons-loading">
            <!-- 加载动画 旋转加载图标 -->
            <div class="loading-spinner"></div>
            <!-- 加载提示文本 -->
            <p>加载武器中...</p>
          </div>
          
          <!-- 武器列表 条件渲染：非加载状态且有武器数据时显示 -->
          <div v-if="!weaponsLoading && heroWeapons.length > 0" class="weapons-list">
            <!-- 武器卡片 遍历武器数组 点击查看武器详情 -->
            <div 
              v-for="weapon in heroWeapons" 
              :key="weapon.weaponId" 
              class="weapon-card clickable-weapon"
              @click="viewWeaponDetail(weapon)"
            >
              <!-- 武器图片 武器图片展示区域 -->
              <div class="weapon-image">
                <!-- 武器图片 动态绑定武器图片源和alt属性 -->
                <img :src="weapon.weaponSkillUrl || '/default-weapon.png'" :alt="weapon.weaponName" />
              </div>
              <!-- 武器信息 武器详细信息区域 -->
              <div class="weapon-info">
                <!-- 武器名称 显示武器名称 -->
                <h4 class="weapon-name">{{ weapon.weaponName }}</h4>
                <!-- 武器属性 武器数值属性展示 -->
                <div class="weapon-stats">
                  <!-- 攻击力属性 显示武器攻击力 -->
                  <span class="stat-item">攻击力: {{ weapon.attack }}</span>
                  <!-- 暴击率属性 显示武器暴击率 -->
                  <span class="stat-item">暴击率: {{ weapon.critRate }}%</span>
                </div>
              </div>
            </div>
          </div>
          
          <!-- 无武器提示 条件渲染：非加载状态且无武器数据时显示 -->
          <div v-if="!weaponsLoading && heroWeapons.length === 0" class="no-weapons">
            <!-- 无武器提示文本 -->
            <p>该英雄暂无推荐武器</p>
          </div>
        </div>
      </aside>
    </div>



    <!-- 加载状态
    
    3. 加载状态（loading-container）
在loading为true时显示，包含加载动画（loading-spinner）和文字提示（“加载中...”）。
动画通过spin关键帧实现旋转效果。
    -->
    <div v-if="loading" class="loading-container">
      <div class="loading-spinner"></div>
      <p>加载中...</p>
    </div>





    <!-- 错误状态
     
    错误状态（error-container）
在error存在时显示，展示错误信息（{{ error }}）和重试按钮（retry-btn）。
点击重试按钮触发loadHeroes重新加载数据。
    -->
    <div v-if="error" class="error-container">
      <p>{{ error }}</p>
      <button @click="loadHeroes" class="retry-btn">重试</button>
    </div>
    



    
    <!-- 技能视频播放器 
     
    技能视频播放器（VideoPlayer）
仅在需要播放技能视频时显示（showSkillVideoPlayer为true且currentSkillVideo存在）。
传入视频地址（video-url）、封面图（poster-url），支持自动播放（autoplay）。
绑定@close和@ended事件，关闭播放器并清空当前视频。
    -->
    <VideoPlayer
      v-if="showSkillVideoPlayer && currentSkillVideo && currentSkillVideo.videoUrl"
      :video-url="currentSkillVideo.videoUrl"
      :poster-url="currentSkillVideo.imageUrl || (selectedHero && selectedHero.largeIconUrl) || defaultVideoPoster"
      :show-modal="true"
      :autoplay="true"
      @close="closeSkillVideoPlayer"
      @ended="closeSkillVideoPlayer"
    />
  </div>
</template>


<!-- 脚本部分 JavaScript逻辑处理部分 负责数据管理、逻辑处理和交互控制 -->
<script>
// 依赖导入 导入所需的API、组件和工具函数
// 英雄数据API 用于获取英雄列表和详情
import { heroApi } from '../api/hero.js'
// 技能数据API 用于获取英雄技能信息
import { skillApi } from '../api/skill.js'
// 武器数据API 用于获取英雄推荐武器
import { weaponApi } from '../api/weapon.js'
// 顶部导航栏组件 页面顶部导航
import TopNavbar from './TopNavbar.vue'
// 路由工具 用于页面跳转
import { useRouter } from 'vue-router'
// 用户状态管理 用于用户登录状态管理
import { useUserStore } from '../stores/user'

// 组件配置 Vue组件选项配置
export default {
  // 组件名称 定义组件名称为HeroPage
  name: 'HeroPage',

  // 注册组件 注册子组件供模板使用
  components: {
    TopNavbar
  },

  // 组合式API设置 获取路由和用户状态管理实例
  setup() {
    // 路由实例 用于页面跳转
    const router = useRouter()
    // 用户状态实例 用于用户状态管理
    const userStore = useUserStore()
    // 返回实例供模板使用
    return { router, userStore }
  },



  // 数据定义 组件响应式数据定义
  data() {
    return {
      // 核心数据 主要业务数据
      heroes: [],    // 英雄列表 所有英雄数据数组 从API加载
      selectedHero: null, // 选中英雄 当前选中的英雄对象 默认选中第一个
      heroSkills: [], // 英雄技能 当前英雄的技能列表数组
      hoveredHero: null, // 悬停英雄 鼠标悬停的英雄对象 用于临时显示技能
      heroWeapons: [], // 英雄武器 当前选中英雄的推荐武器列表

      // 状态控制 加载和错误状态管理
      loading: true,   // 全局加载状态 整体数据加载状态
      skillsLoading: false, // 技能加载状态 技能数据加载状态
      weaponsLoading: false, // 武器加载状态 武器数据加载状态
      error: null,  // 错误信息 加载失败时的错误信息

      // 缓存机制 数据缓存避免重复请求
      skillsCache: {}, // 技能缓存 按heroId缓存技能数据
      weaponsCache: {}, // 武器缓存 按heroId缓存武器数据

      // 视频播放器 技能视频播放相关
      showSkillVideoPlayer: false,   // 视频播放器显示状态 控制视频播放器显示隐藏
      currentSkillVideo: null,  // 当前播放视频 当前播放的技能视频信息对象

      // 默认图片 默认占位图片URL
      defaultHeroImage: 'https://fastcdn.mihoyo.com/content-v2/bh3/157811/92333adce61e1a9e75591e2741dcfd97_7957877470594159892.png', // 英雄大图默认图
      defaultAvatarImage: 'https://fastcdn.mihoyo.com/content-v2/bh3/156251/ea55b240730debec811239cbb393a7bb_2296978660569028145.png' // 英雄头像默认图
    }
  },


  // 生命周期钩子 组件挂载后执行
  mounted() {
    // 页面挂载时加载英雄数据 初始化页面数据
    this.loadHeroes()
  },

  // 方法定义 组件方法集合
  methods: {
    // 加载英雄数据 从API获取所有英雄数据并初始化页面
    async loadHeroes() {
      try {
        // 设置加载状态 开始加载数据
        this.loading = true
        // 清除错误信息 重置错误状态
        this.error = null
        
        // 调用API获取英雄数据 从后端获取所有英雄信息
        const response = await heroApi.getAllHeroes()
        // 检查API响应状态 判断请求是否成功
        if (response.code === 0) {
          // 设置英雄数据 将API数据赋值给heroes数组
          this.heroes = response.data || []
          // 默认选择第一个英雄 初始化选中状态
          if (this.heroes.length > 0) {
            // 设置选中英雄 选择第一个英雄作为默认选中
            this.selectedHero = this.heroes[0]
            // 并行加载英雄技能和武器 同时加载第一个英雄的技能和推荐武器
            await Promise.all([
              this.loadHeroSkills(this.heroes[0].id),
              this.loadHeroWeapons(this.heroes[0].id)
            ])
          }
        } else {
          // 设置错误信息 API返回错误时显示错误信息
          this.error = response.message || '获取英雄数据失败'
        }
      } catch (err) {   // 异常处理 网络错误或其他异常
        console.error('加载英雄数据失败:', err) // 错误日志 输出错误信息
        // 设置网络错误信息 显示用户友好的错误提示
        this.error = '网络错误，请稍后重试'
        // 使用模拟数据作为后备 保证页面可用性
        this.loadMockData()
      } finally {
        // 结束加载状态 无论成功失败都要结束加载
        this.loading = false
        // 预加载视频缩略图 DOM更新后预加载视频缩略图
        this.$nextTick(() => {
          this.preloadVideoThumbnails()
        })
      }
    },
    
    loadMockData() {    //加载模拟英雄数据（开发 / 测试用），包含 3 个示例英雄，避免无网络时页面空白。
      // 模拟数据，用于开发和测试
      this.heroes = [
        {
          id: 1,
          name: '极地战刃',
          favorability: '无量塔姬子',
          birthday: '6月11日',
          combatStyle: '大剑',
          description: '无量塔姬子的战斗装甲，擅长使用大剑进行近战攻击。',
          imageUrl: this.defaultHeroImage,
          avatarUrl: this.defaultAvatarImage
        },
        {
          id: 2,
          name: '白夜执事',
          favorability: '丽塔·洛丝薇瑟',
          birthday: '4月1日',
          combatStyle: '镰刀',
          description: '丽塔的专属战斗装甲，优雅而致命的战斗风格。',
          imageUrl: this.defaultHeroImage,
          avatarUrl: this.defaultAvatarImage
        },
        {
          id: 3,
          name: '雷电女王',
          favorability: '雷电芽衣',
          birthday: '4月13日',
          combatStyle: '太刀',
          description: '雷电芽衣的强力装甲，掌控雷电之力。',
          imageUrl: this.defaultHeroImage,
          avatarUrl: this.defaultAvatarImage
        }
      ]
      this.selectedHero = this.heroes[0]
      this.error = null
    },
    

    //切换选中英雄   作用：更新selectedHero为点击的英雄，并加载该英雄的技能和武器。
    async selectHero(hero) {
      this.selectedHero = hero
      // 选中后加载该英雄技能和推荐武器
      await Promise.all([
        this.loadHeroSkills(hero.id),
        this.loadHeroWeapons(hero.id)
      ])
    },
    
    // 鼠标移入缩略图：仅展示该英雄技能，不改变选中英雄
    async handleThumbEnter(hero) {
      this.hoveredHero = hero
      await this.loadHeroSkills(hero.id)
    },
    
    // 鼠标移出缩略图：恢复展示选中英雄的技能
    async handleThumbLeave() {
      this.hoveredHero = null
      if (this.selectedHero) {
        await this.loadHeroSkills(this.selectedHero.id)
      }
    },
    


    // 加载英雄技能列表（带缓存）

    //loadHeroSkills(heroId)：加载指定英雄的技能（带缓存）。
//逻辑：若heroId为空则清空技能列表 → 若缓存中存在则直接使用 → 否则调用skillApi.getSkillsByHeroId(heroId)请求数据，成功后缓存并赋值heroSkills。
//调试：包含详细日志，打印请求参数、响应数据和技能列表结构。
    async loadHeroSkills(heroId) {
      
      if (!heroId) {
        this.heroSkills = []    //清空技能列表
        return
      }
      
      // 命中缓存，直接使用
      if (this.skillsCache && this.skillsCache[heroId]) {
        this.heroSkills = this.skillsCache[heroId]
        return
      }
      
      try {
        this.skillsLoading = true

        //调用skillApi.getSkillsByHeroId(heroId)请求数据，成功后缓存并赋值heroSkills
        const response = await skillApi.getSkillsByHeroId(heroId)    
        
        if (response.code === 0) {
          const list = response.data || []
          // 缓存结果
          this.skillsCache[heroId] = list
          this.heroSkills = list
        } else {
          console.error('获取技能数据失败:', response.message)
          this.heroSkills = []
        }
      } catch (err) {
        console.error('加载技能数据失败:', err)
        console.error('错误详情:', err.message);
        console.error('错误堆栈:', err.stack);
        this.heroSkills = []
      } finally {
        this.skillsLoading = false
      }
    },
    
    // 强制刷新数据
    async forceRefresh() {   //强制刷新所有数据（调用loadHeroes），用于手动更新。
      await this.loadHeroes()
      this.$message?.success('数据已刷新')
    },
    

    


//技能视频相关（playSkillVideo和closeSkillVideoPlayer）
//作用：控制技能视频播放器的显示 / 隐藏，设置当前播放的视频。

    playSkillVideo(skill) {   //赋值currentSkillVideo并显示播放器（showSkillVideoPlayer: true）
      // 播放技能视频的逻辑
      if (skill && skill.videoUrl) {
        this.currentSkillVideo = skill
        this.showSkillVideoPlayer = true
      } else {
        this.$message?.info('该技能暂无视频')
      }
    },
    
    closeSkillVideoPlayer() {   //隐藏播放器并清空当前视频。
      this.showSkillVideoPlayer = false
      this.currentSkillVideo = null
    },
    





    // 查看技能详情     
    viewSkillDetail(skill) {      //技能详情：路由跳转到SkillDetail页面，携带skillId参数。
      if (skill && skill.skillId) {
        this.$router.push({ name: 'SkillDetail', params: { skillId: skill.skillId } })
      } else {
        console.error('技能ID不存在:', skill)
      }
    },

      // 加载英雄推荐武器列表（带缓存）
      async loadHeroWeapons(heroId) {
        if (!heroId) {
          this.heroWeapons = []
          return
        }
        
        // 命中缓存，直接使用
        if (this.weaponsCache && this.weaponsCache[heroId]) {
          this.heroWeapons = this.weaponsCache[heroId]
          return
        }
        
        try {
          this.weaponsLoading = true
          
          const response = await weaponApi.getWeaponsByHeroId(heroId)
          
          if (response.code === 0) {
            this.heroWeapons = response.data || []
            // 缓存武器数据
            if (!this.weaponsCache) {
              this.weaponsCache = {}
            }
            this.weaponsCache[heroId] = this.heroWeapons
          } else {
            console.error('武器数据加载失败:', response.message)
            this.heroWeapons = []
          }
        } catch (error) {
          console.error('加载武器数据时出错:', error)
          this.heroWeapons = []
        } finally {
          this.weaponsLoading = false
        }
      },



      
      // 查看武器详情     //路由跳转到/weapon页面，携带weaponId参数。
      viewWeaponDetail(weapon) {
        // 跳转到武器页面并高亮显示该武器
        this.router.push({
          path: '/weapon',
          query: { weaponId: weapon.id }
        })
      },
      



      //导航与弹窗（handleNavigation、showLogin、showRegister、handleLogout）
//作用：处理页面导航、触发登录 / 注册弹窗、用户注销。

  // 顶部导航栏事件处理
      handleNavigation(page) {
        this.router.push(`/${page === 'home' ? '' : page}`)
      },

      //触发登录弹窗（通过window.dispatchEvent发送自定义事件）
      showLogin() {  
        // 触发登录弹窗事件
        window.dispatchEvent(new CustomEvent('show-login-modal'))
      },
      
      //触发注册弹窗（通过window.dispatchEvent发送自定义事件）
      showRegister() {    
        // 触发注册弹窗事件
        window.dispatchEvent(new CustomEvent('show-register-modal'))
      },

      //handleLogout()：处理用户登出（调用userStore.logout()，需确认弹窗）。
      async handleLogout() {   
        if (confirm('确定要退出登录吗？')) {
          await this.userStore.logout()
        }
      }
  }
}





</script>  
<!-- 样式部分 CSS样式定义 通过scoped隔离样式避免全局污染 -->
<style scoped>

/* 页面容器 英雄页面主容器样式 */
.hero-page {
  padding: 0; /* 页面容器 内边距：无 */
  background: transparent; /* 页面容器 背景：透明 */
}

/* 刷新控件 刷新按钮容器和按钮样式 */
.refresh-controls {
  display: flex; /* 刷新控件 布局：弹性布局 */
  justify-content: flex-end; /* 刷新控件 对齐：右对齐 */
  margin-bottom: 20px; /* 刷新控件 外边距：底部20px */
}

.refresh-btn {
  display: flex; /* 刷新按钮 布局：弹性布局 */
  align-items: center; /* 刷新按钮 对齐：垂直居中 */
  gap: 8px; /* 刷新按钮 间距：8px */
  padding: 10px 20px; /* 刷新按钮 内边距：上下10px 左右20px */
  background: linear-gradient(45deg, #4ecdc4, #44a08d); /* 刷新按钮 背景：渐变色 */
  color: white; /* 刷新按钮 文字颜色：白色 */
  border: none; /* 刷新按钮 边框：无 */
  border-radius: 6px; /* 刷新按钮 圆角：6px */
  cursor: pointer; /* 刷新按钮 鼠标样式：手型 */
  font-size: 14px; /* 刷新按钮 字体大小：14px */
  font-weight: 500; /* 刷新按钮 字体粗细：中等 */
  transition: all 0.3s ease; /* 刷新按钮 过渡：所有属性0.3秒缓动 */
}

.refresh-btn:hover:not(:disabled) {
  transform: translateY(-2px); /* 刷新按钮悬停 变换：向上移动2px */
  box-shadow: 0 4px 12px rgba(78, 205, 196, 0.4); /* 刷新按钮悬停 阴影：蓝绿色阴影 */
}

.refresh-btn:disabled {
  opacity: 0.6; /* 刷新按钮禁用 透明度：60% */
  cursor: not-allowed; /* 刷新按钮禁用 鼠标样式：禁止 */
  transform: none; /* 刷新按钮禁用 变换：无 */
}

.refresh-icon {
  font-size: 16px; /* 刷新图标 字体大小：16px */
  animation: none; /* 刷新图标 动画：无 */
}

.refresh-btn:not(:disabled):hover .refresh-icon {
  animation: rotate 1s linear infinite; /* 刷新图标悬停 动画：无限旋转 */
}

@keyframes rotate {
  from { transform: rotate(0deg); } /* 旋转动画 起始：0度 */
  to { transform: rotate(360deg); } /* 旋转动画 结束：360度 */
}

.hero-page {
  height: 100vh; /* 英雄页面 高度：视窗高度100% */
  color: white; /* 英雄页面 文字颜色：白色 */
  background: rgba(0, 0, 0, 0.7); /* 英雄页面 背景：半透明黑色 */
  padding-top: 70px; /* 英雄页面 顶部内边距：70px 为顶部导航栏留出空间 */
}

.page-header {
  text-align: center; /* 页面头部 文本对齐：居中 */
  margin-bottom: 40px; /* 页面头部 底部外边距：40px */
}

.page-title {
  font-size: 2.5rem; /* 页面标题 字体大小：2.5rem */
  font-weight: bold; /* 页面标题 字体粗细：粗体 */
  margin-bottom: 10px; /* 页面标题 底部外边距：10px */
  background: linear-gradient(45deg, #ff6b6b, #4ecdc4); /* 页面标题 背景：渐变色 */
  -webkit-background-clip: text; /* 页面标题 背景裁剪：文字 */
  -webkit-text-fill-color: transparent; /* 页面标题 文字填充：透明 */
  background-clip: text; /* 页面标题 背景裁剪：文字 */
}

.page-subtitle {
  font-size: 1.2rem; /* 页面副标题 字体大小：1.2rem */
  color: #b0b0b0; /* 页面副标题 文字颜色：浅灰色 */
  margin: 0; /* 页面副标题 外边距：无 */
}

.hero-container {
  max-width: 1200px; /* 英雄容器 最大宽度：1200px */
  margin: 0 auto; /* 英雄容器 外边距：水平居中 */
}

.hero-main-display {
  display: flex; /* 英雄主展示 布局：弹性布局 */
  gap: 40px; /* 英雄主展示 间距：40px */
  margin-bottom: 40px; /* 英雄主展示 底部外边距：40px */
  background: rgba(255, 255, 255, 0.05); /* 英雄主展示 背景：半透明白色 */
  border-radius: 20px; /* 英雄主展示 圆角：20px */
  padding: 30px; /* 英雄主展示 内边距：30px */
  backdrop-filter: blur(10px); /* 英雄主展示 背景滤镜：模糊10px */
  border: 1px solid rgba(255, 255, 255, 0.1); /* 英雄主展示 边框：半透明白色1px */
}

.hero-image-section {
  flex: 1; /* 英雄图片区域 弹性：1 */
  display: flex; /* 英雄图片区域 布局：弹性布局 */
  justify-content: center; /* 英雄图片区域 水平对齐：居中 */
  align-items: center; /* 英雄图片区域 垂直对齐：居中 */
}

.hero-main-image {
  width: 400px; /* 英雄主图 宽度：400px */
  height: 500px; /* 英雄主图 高度：500px */
  border-radius: 15px; /* 英雄主图 圆角：15px */
  overflow: hidden; /* 英雄主图 溢出：隐藏 */
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); /* 英雄主图 阴影：黑色阴影 */
}

.hero-main-image img {
  width: 100%; /* 英雄主图图片 宽度：100% */
  height: 100%; /* 英雄主图图片 高度：100% */
  object-fit: cover; /* 英雄主图图片 对象适应：覆盖 */
}

.hero-info-section {
  flex: 1; /* 英雄信息区域 弹性：1 */
  display: flex; /* 英雄信息区域 布局：弹性布局 */
  flex-direction: column; /* 英雄信息区域 弹性方向：列 */
  justify-content: center; /* 英雄信息区域 垂直对齐：居中 */
}

.hero-name {
  font-size: 3rem; /* 英雄名称 字体大小：3rem */
  font-weight: bold; /* 英雄名称 字体粗细：粗体 */
  margin-bottom: 10px; /* 英雄名称 底部外边距：10px */
  color: #ff6b6b; /* 英雄名称 文字颜色：红色 */
}

.hero-title {
  font-size: 1.5rem; /* 英雄称号 字体大小：1.5rem */
  font-weight: 500; /* 英雄称号 字体粗细：中等 */
  margin-bottom: 20px; /* 英雄称号 底部外边距：20px */
  color: #4ecdc4; /* 英雄称号 文字颜色：青色 */
  font-style: italic; /* 英雄称号 字体样式：斜体 */
}

.hero-details {
  margin-bottom: 30px; /* 英雄详情 底部外边距：30px */
}

.hero-attribute {
  display: flex; /* 英雄属性 布局：弹性布局 */
  margin-bottom: 15px; /* 英雄属性 底部外边距：15px */
  font-size: 1.1rem; /* 英雄属性 字体大小：1.1rem */
}

.hero-attribute .label {
  color: #b0b0b0; /* 英雄属性标签 文字颜色：浅灰色 */
  min-width: 100px; /* 英雄属性标签 最小宽度：100px */
}

.hero-attribute .value {
  color: white; /* 英雄属性值 文字颜色：白色 */
  font-weight: 500; /* 英雄属性值 字体粗细：中等 */
}

.hero-description {
  margin-bottom: 15px; /* 英雄描述 底部外边距：15px */
  font-size: 1rem; /* 英雄描述 字体大小：1rem */
  line-height: 1.6; /* 英雄描述 行高：1.6 */
  color: #d0d0d0; /* 英雄描述 文字颜色：浅灰色 */
  padding: 15px; /* 英雄描述 内边距：15px */
  background: rgba(0, 0, 0, 0.6); /* 英雄描述 背景：半透明黑色 */
  border-radius: 12px; /* 英雄描述 圆角：12px */
  border: 1px solid rgba(78, 205, 196, 0.3); /* 英雄描述 边框：半透明青色 */
}

.hero-actions {
  display: flex; /* 英雄操作 布局：弹性布局 */
  align-items: center; /* 英雄操作 垂直对齐：居中 */
}

.play-btn {
  width: 60px; /* 播放按钮 宽度：60px */
  height: 60px; /* 播放按钮 高度：60px */
  border-radius: 50%; /* 播放按钮 圆角：50% 圆形 */
  background: linear-gradient(45deg, #ff6b6b, #4ecdc4); /* 播放按钮 背景：渐变色 */
  border: none; /* 播放按钮 边框：无 */
  cursor: pointer; /* 播放按钮 光标：指针 */
  display: flex; /* 播放按钮 布局：弹性布局 */
  align-items: center; /* 播放按钮 垂直对齐：居中 */
  justify-content: center; /* 播放按钮 水平对齐：居中 */
  transition: all 0.3s ease; /* 播放按钮 过渡：所有属性0.3秒 */
}

.play-btn:hover {
  transform: scale(1.1); /* 播放按钮悬停 变换：放大1.1倍 */
  box-shadow: 0 5px 20px rgba(255, 107, 107, 0.4); /* 播放按钮悬停 阴影：红色阴影 */
}

.play-icon {
  color: white; /* 播放图标 文字颜色：白色 */
  font-size: 1.5rem; /* 播放图标 字体大小：1.5rem */
  margin-left: 3px; /* 播放图标 左外边距：3px */
}

.hero-thumbnail-list {
  display: flex; /* 英雄缩略图列表 布局：弹性布局 */
  gap: 15px; /* 英雄缩略图列表 间距：15px */
  padding: 20px; /* 英雄缩略图列表 内边距：20px */
  background: rgba(255, 255, 255, 0.05); /* 英雄缩略图列表 背景：半透明白色 */
  border-radius: 15px; /* 英雄缩略图列表 圆角：15px */
  overflow-x: auto; /* 英雄缩略图列表 水平溢出：自动滚动 */
  position: relative; /* 英雄缩略图列表 定位：相对 */
  align-items: center; /* 英雄缩略图列表 垂直对齐：居中 */
}

.hero-thumbnail {
  flex-shrink: 0; /* 英雄缩略图 弹性收缩：0 不收缩 */
  width: 80px; /* 英雄缩略图 宽度：80px */
  height: 80px; /* 英雄缩略图 高度：80px */
  border-radius: 50%; /* 英雄缩略图 圆角：50% 圆形 */
  overflow: hidden; /* 英雄缩略图 溢出：隐藏 */
  cursor: pointer; /* 英雄缩略图 光标：指针 */
  transition: all 0.3s ease; /* 英雄缩略图 过渡：所有属性0.3秒 */
  border: 3px solid transparent; /* 英雄缩略图 边框：3px透明 */
}

.hero-thumbnail:hover {
  transform: scale(1.1); /* 英雄缩略图悬停 变换：放大1.1倍 */
}

.hero-thumbnail.active {
  border-color: #ff6b6b; /* 英雄缩略图激活 边框颜色：红色 */
  box-shadow: 0 0 20px rgba(255, 107, 107, 0.5); /* 英雄缩略图激活 阴影：红色发光 */
}

.hero-thumbnail img {
  width: 100%; /* 英雄缩略图图片 宽度：100% */
  height: 100%; /* 英雄缩略图图片 高度：100% */
  object-fit: cover; /* 英雄缩略图图片 对象适应：覆盖 */
}

.nav-arrow {
  position: absolute; /* 导航箭头 定位：绝对 */
  top: 50%; /* 导航箭头 顶部：50% */
  transform: translateY(-50%); /* 导航箭头 变换：垂直居中 */
  width: 40px; /* 导航箭头 宽度：40px */
  height: 40px; /* 导航箭头 高度：40px */
  background: rgba(255, 255, 255, 0.2); /* 导航箭头 背景：半透明白色 */
  border-radius: 50%; /* 导航箭头 圆角：50% 圆形 */
  display: flex; /* 导航箭头 布局：弹性布局 */
  align-items: center; /* 导航箭头 垂直对齐：居中 */
  justify-content: center; /* 导航箭头 水平对齐：居中 */
  cursor: pointer; /* 导航箭头 光标：指针 */
  transition: all 0.3s ease; /* 导航箭头 过渡：所有属性0.3秒 */
  z-index: 10; /* 导航箭头 层级：10 */
}

.nav-arrow:hover {
  background: rgba(255, 255, 255, 0.3); /* 导航箭头悬停 背景：更亮的半透明白色 */
}

.nav-arrow-right {
  right: 10px; /* 右导航箭头 右边距：10px */
}

.nav-arrow span {
  font-size: 1.5rem; /* 导航箭头图标 字体大小：1.5rem */
  color: white; /* 导航箭头图标 文字颜色：白色 */
}

.loading-container,
.error-container {
  display: flex; /* 加载/错误容器 布局：弹性布局 */
  flex-direction: column; /* 加载/错误容器 弹性方向：列 */
  align-items: center; /* 加载/错误容器 水平对齐：居中 */
  justify-content: center; /* 加载/错误容器 垂直对齐：居中 */
  min-height: 400px; /* 加载/错误容器 最小高度：400px */
  text-align: center; /* 加载/错误容器 文本对齐：居中 */
}

.loading-spinner {
  width: 50px; /* 加载旋转器 宽度：50px */
  height: 50px; /* 加载旋转器 高度：50px */
  border: 4px solid rgba(255, 255, 255, 0.3); /* 加载旋转器 边框：半透明白色 */
  border-top: 4px solid #ff6b6b; /* 加载旋转器 顶部边框：红色 */
  border-radius: 50%; /* 加载旋转器 圆角：50% 圆形 */
  animation: spin 1s linear infinite; /* 加载旋转器 动画：旋转1秒无限循环 */
  margin-bottom: 20px; /* 加载旋转器 底部外边距：20px */
}

@keyframes spin {
  0% { transform: rotate(0deg); } /* 旋转动画 0%：0度 */
  100% { transform: rotate(360deg); } /* 旋转动画 100%：360度 */
}

.retry-btn {
  padding: 10px 20px; /* 重试按钮 内边距：10px 20px */
  background: #ff6b6b; /* 重试按钮 背景：红色 */
  color: white; /* 重试按钮 文字颜色：白色 */
  border: none; /* 重试按钮 边框：无 */
  border-radius: 5px; /* 重试按钮 圆角：5px */
  cursor: pointer; /* 重试按钮 光标：指针 */
  margin-top: 10px; /* 重试按钮 顶部外边距：10px */
  transition: background 0.3s ease; /* 重试按钮 过渡：背景0.3秒 */
}

.retry-btn:hover {
  background: #ff5252; /* 重试按钮悬停 背景：更深的红色 */
}

/* 响应式设计 - 移动端适配 */
@media (max-width: 768px) {
  .hero-main-display {
    flex-direction: column; /* 移动端 英雄主展示 弹性方向：列布局 */
    text-align: center; /* 移动端 英雄主展示 文本对齐：居中 */
  }
  
  .hero-main-image {
    width: 300px; /* 移动端 英雄主图 宽度：300px */
    height: 400px; /* 移动端 英雄主图 高度：400px */
  }
  
  .hero-name {
    font-size: 2rem; /* 移动端 英雄名称 字体大小：2rem */
  }
  
  .page-title {
    font-size: 2rem; /* 移动端 页面标题 字体大小：2rem */
  }
}

/* 三栏英雄展示布局（左中右） - 网格布局系统 */
.valkyrie-layout {
  display: grid; /* 三栏布局 布局：网格布局 */   
  grid-template-columns: 260px 1fr 600px; /* 三栏布局 网格列：左侧260px 中间自适应 右侧600px */
  gap: 0; /* 三栏布局 间距：0 保证三个区域之间没有间隙 */
  width: 100vw; /* 三栏布局 宽度：视窗宽度100% 占满视口宽度 */
  height: 100vh; /* 三栏布局 高度：视窗高度100% 充满全屏高度 */
  padding: 0; /* 三栏布局 内边距：0 去除所有内边距实现无缝全屏 */
  margin: 0; /* 三栏布局 外边距：0 去除外边距 */
  position: relative; /* 三栏布局 定位：相对 确保三个区域之间没有间隙 */
  top: 0; /* 三栏布局 顶部：0 顶部对齐 */
  left: 0; /* 三栏布局 左侧：0 左侧对齐 */
  z-index: 1; /* 三栏布局 层级：1 层级设置 */
}







/* 左侧栏（valkyrie-left）：英雄列表区域 */
.valkyrie-left {
  background: transparent; /* 左侧栏 背景：透明 改为透明背景 */
  border-radius: 12px; /* 左侧栏 圆角：12px */
  padding: 12px 8px; /* 左侧栏 内边距：12px 8px */
  overflow-y: auto; /* 左侧栏 垂直溢出：自动滚动 支持纵向滚动，方便浏览大量英雄 */
}

/* 英雄名字列表：通过v-for遍历heroes数组渲染所有英雄名称 */
.name-list { 
  list-style: none; /* 英雄名字列表 列表样式：无 */
  margin: 0; /* 英雄名字列表 外边距：0 */
  padding: 0; /* 英雄名字列表 内边距：0 */
  display: flex; /* 英雄名字列表 布局：弹性布局 */
  flex-direction: column; /* 英雄名字列表 弹性方向：列 */
  gap: 8px; /* 英雄名字列表 间距：8px */
}

/* 每个列表项：点击时触发selectHero方法，切换选中的英雄 */
.name-item { 
  cursor: pointer; /* 英雄名字项 光标：指针 */
  display: flex; /* 英雄名字项 布局：弹性布局 */
  align-items: center; /* 英雄名字项 垂直对齐：居中 */
  gap: 10px; /* 英雄名字项 间距：10px */
  padding: 10px 12px; /* 英雄名字项 内边距：10px 12px */
  border-radius: 8px; /* 英雄名字项 圆角：8px */
  color: #cfd8dc; /* 英雄名字项 文字颜色：浅灰蓝色 */
  transition: all 0.25s ease; /* 英雄名字项 过渡：所有属性0.25秒 */
  font-size: 18px; /* 英雄名字项 字体大小：18px */
}

.name-item:hover { 
  background: transparent; /* 英雄名字项悬停 背景：透明 */
  color: transparent; /* 英雄名字项悬停 文字颜色：透明 */
  transform: translateX(4px); /* 英雄名字项悬停 变换：右移4px */
}

.name-item.active { 
  background: rgba(78, 205, 196, 0.2); /* 英雄名字项激活 背景：半透明青色 */
  color: #fff; /* 英雄名字项激活 文字颜色：白色 */
}

.name-item .dot { 
  width: 6px; /* 英雄名字项圆点 宽度：6px */
  height: 6px; /* 英雄名字项圆点 高度：6px */
  border-radius: 50%; /* 英雄名字项圆点 圆角：50% 圆形 */
  background: #4ecdc4; /* 英雄名字项圆点 背景：青色 */
}

/* 中间栏（valkyrie-center）：英雄大图展示区域 */
/* 中央展示区 - 英雄大图的中央展示区域 */
.valkyrie-center { 
  display: flex; /* 中央展示区 布局：弹性布局 */
  align-items: center; /* 中央展示区 垂直对齐：居中 */
  justify-content: center; /* 中央展示区 水平对齐：居中 */
  position: relative; /* 中央展示区 定位：相对 */
  overflow: visible; /* 中央展示区 溢出：可见 */
  background: radial-gradient(ellipse at center, rgba(255,255,255,0.18), rgba(255,255,255,0.15) 60%); /* 中央展示区 背景：径向渐变，营造聚光灯效果 */
  border-radius: 0; /* 中央展示区 圆角：0 */
  z-index: 3; /* 中央展示区 层级：3 确保在最上层显示 */
}

/* 英雄插画容器 - 英雄插画的直接容器 */
.hero-illus { 
  width: 100%; /* 英雄插画容器 宽度：100% 占满父容器 */
  height: 100%; /* 英雄插画容器 高度：100% 占满父容器 */
  display: flex; /* 英雄插画容器 布局：弹性布局 */
  align-items: center; /* 英雄插画容器 垂直对齐：居中 */
  justify-content: center; /* 英雄插画容器 水平对齐：居中 */
  pointer-events: none; /* 英雄插画容器 鼠标事件：禁用 */
  position: relative; /* 英雄插画容器 定位：相对 */
  z-index: 3; /* 英雄插画容器 层级：3 */
}

/* 英雄插画 - 英雄大图的具体展示 */
.hero-illus img { 
  max-height: 90vh; /* 英雄插画 最大高度：90vh */
  width: auto; /* 英雄插画 宽度：自适应 */
  object-fit: contain; /* 英雄插画 对象适应：包含 保持图片比例，不超出容器 */
  filter: drop-shadow(0 20px 40px rgba(0,0,0,0.35)); /* 英雄插画 滤镜：阴影 增加立体感 */
}

/* 左侧栏（valkyrie-left）：英雄列表 - 重复定义样式 */
.valkyrie-left { 
  background: rgba(255, 255, 255, 0.18); /* 左侧栏重复 背景：半透明白色 */
  border-radius: 0; /* 左侧栏重复 圆角：0 */
  padding: 20px; /* 左侧栏重复 内边距：20px */
  display: flex; /* 左侧栏重复 布局：弹性布局 */
  flex-direction: column; /* 左侧栏重复 弹性方向：列 */
  gap: 16px; /* 左侧栏重复 间距：16px */
  overflow-y: auto; /* 左侧栏重复 垂直溢出：自动滚动 */
  position: relative; /* 左侧栏重复 定位：相对 */
  z-index: 1; /* 左侧栏重复 层级：1 */
}

/*(.valkyrie-left .codename) 
- 设置元素底部外边距为20像素*/
.valkyrie-left .codename { margin-bottom: 20px; }

/* 右侧栏（valkyrie-right）：英雄详情
- 背景 ：半透明（rgba(255, 255, 255, 0.18)）
- 圆角 ：border-radius: 0
- 内边距 ：padding: 12px
- 垂直排列，间距10px
- 滚动 ：overflow-y: auto 支持垂直滚动*/
.valkyrie-right { background: rgba(255, 255, 255, 0.18); border-radius: 0; padding: 12px; display: flex; flex-direction: column; gap: 10px; overflow-y: auto; position: relative; z-index: 1; transform: none; }

.meta-header { display: flex; justify-content: flex-end; }
.phase-tabs .tab { color: rgba(255, 255, 255, 0.5); margin-left: 8px; }
.phase-tabs .tab.active { color: #4ecdc4; }

.codename { font-size: 28px; font-weight: 800; margin: 0; color: #fff; } 
/*(.meta-list)   
- 作用 ：英雄基本信息的容器
- 布局 ：垂直排列，行间距8px*/
.meta-list { display: flex; flex-direction: column; gap: 8px; }

/*(.meta-row) 
- 作用 ：单行信息显示（如姓名、星环分野）
- 标签 ：100px最小宽度，确保对齐
- 数值 ：白色显示，突出重要信息*/
.meta-row { display: flex; gap: 12px; font-size: 16px; color: #d0d0d0; }
.meta-row .label { color: rgba(255, 255, 255, 0.6); min-width: 100px; text-align: left; }
.meta-row .value { color: #fff; }

/*(.meta-row-double) 
 - 作用 ：双列信息显示（如称谓+属性、作战方式+伤害类型）
- 布局 ：两列等宽分布
- 对齐 ：标签统一100px宽度，确保完美对齐*/
.meta-row-double { display: flex; gap: 20px; font-size: 16px; color: #d0d0d0; }

/*- display: flex - 设置为弹性布局，让标签和数值水平排列
- gap: 8px - 标签和数值之间的间距为8像素
- flex: 1 - 弹性增长，每个meta-item占据相等的空间 */
.meta-item { display: flex; gap: 8px; flex: 1; }

/*- color: rgba(255, 255, 255, 0.6) - 半透明白色，60%透明度，显示为灰白色
- min-width: 100px - 最小宽度100像素，确保所有标签对齐
- text-align: left - 文字左对齐 */
.meta-item .label { color: rgba(255, 255, 255, 0.6); min-width: 100px; text-align: left; }

/*color: #fff - 纯白色，突出显示重要信息 */
.meta-item .value { color: #fff; }

/* 姓名旁边的小图标样式 */
.name-with-icon {
  align-items: center;
}

.name-icon-group {
  display: flex;
  align-items: center;
  gap: 10px;
}

.hero-mini-icon {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 2px solid rgba(78, 205, 196, 0.5);
  object-fit: cover;
  transition: all 0.3s ease;
}

.hero-mini-icon:hover {
  border-color: #4ecdc4;
  transform: scale(1.1);
}







/* 背景介绍区域样式 */
.background-description {
  margin: 15px 0;
  padding: 15px;
  background: transparent;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  transition: all 0.3s ease;
}

.background-description:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 25px rgba(78, 205, 196, 0.2);
}

.description-header {
  margin-bottom: 15px;
}

.description-title {
  font-size: 16px;
  font-weight: 600;
  color: #4ecdc4;
  margin: 0 0 8px 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

.description-title::before {
  content: '📖';
  font-size: 14px;
}

.description-divider {
  height: 2px;
  background: linear-gradient(90deg, #4ecdc4, transparent);
  border-radius: 1px;
  width: 60px;
}

.description-content {
  position: relative;
}

/* 背景介绍文字样式 */
.description-text {
  font-size: 16px;  /*背景介绍文字大小*/
  line-height: 1.6;   /*- 设置行高为字体大小的1.6倍（即16px × 1.6 = 25.6px）*/
  color: #ffffff;   /*角色背景文字颜色*/
  margin: 0;  /*- 清除所有外边距（上下左右都为0）避免段落默认的外边距影响布局*/
  text-align: justify; /*- 设置文字对齐方式为两端对齐 让每行文字（除最后一行）都充满整行宽度 */
  word-wrap: break-word;/*- 设置单词换行规则 当单词太长时允许在单词内部换行，防止溢出容器 */
  text-indent: 2em;  /*设置首行缩进为2个字符的宽度 */
}

.description-text::first-letter {  /*首字符标红 */
  font-size: 1.2em;
  font-weight: 600;
  color: #ff6b6b;
}

/*角色右侧缩略图 */

/*缩略图容器  - 创建一个水平排列的缩略图容器
- display: flex - 使用弹性布局，子元素水平排列
- gap: 10px - 缩略图之间间距10像素
- margin-top: 16px - 容器顶部外边距16像素
- padding-top: 8px - 容器顶部内边距8像素
- overflow-x: auto - 当内容超出宽度时显示水平滚动条*/
.thumb-strip { display: flex; gap: 10px; margin-top: 16px; padding-top: 8px; overflow-x: auto; }
/*单个缩略图样式 - 作用 ：设置每个缩略图的基本样式
- width: 56px; height: 56px - 固定尺寸56×56像素
- border-radius: 50% - 圆形显示
- overflow: hidden - 隐藏超出圆形边界的内容
- border: 2px solid transparent - 透明边框（为激活状态预留空间）
- flex: 0 0 auto - 不伸缩，保持固定大小
- cursor: pointer - 鼠标悬停时显示手型光标
- transition - 变换和边框颜色的过渡动画*/
.mini-thumb { width: 56px; height: 56px; border-radius: 50%; overflow: hidden; border: 2px solid transparent; flex: 0 0 auto; cursor: pointer; transition: transform 0.2s, border-color 0.2s; }
/*缩略图内的图片 - 作用：让图片完美填充圆形容器
- object-fit: cover - 保持比例裁剪图片以填满容器*/
.mini-thumb img { width: 100%; height: 100%; object-fit: cover; }
/*悬停效果 作用 ：鼠标悬停时缩略图放大6%，提供交互反馈 */
.mini-thumb:hover { transform: scale(1.06); }
/*激活状态  - 作用 ：当前选中的缩略图样式
- border-color: #4ecdc4 - 青绿色边框
- box-shadow - 青绿色发光效果*/
.mini-thumb.active { border-color: #4ecdc4; box-shadow: 0 0 12px rgba(78,205,196,0.5); }






/* 技能展示区域样式 */
.skills-section {  /*技能展示区域的主容器*/
  margin-top: 15px;
  padding: 0;
}

.skills-header {  /*技能区域标题头部（居中对齐） */
  text-align: center;
  margin-bottom: 15px;
}

.skills-title {    /*"技能展示"标题样式（青绿色，带阴影效果）*/
  font-size: 20px;
  font-weight: 600;
  color: #4ecdc4;
  margin: 0 0 10px 0;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

.skills-divider { /*标题下方的渐变分隔线 */
  height: 2px;
  background: linear-gradient(90deg, transparent, #4ecdc4, transparent);
  border-radius: 1px;
  margin: 0 auto;
  width: 120px;
}

.skills-loading {  /*技能加载中的提示样式 */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
  color: rgba(255, 255, 255, 0.8);
  font-size: 12px;
}

.skills-list {  /*技能卡片的垂直列表容器*/
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 15px;
}

.skill-card {  /*单个技能卡片的基础样式（半透明黑色背景，毛玻璃效果）*/
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(78, 205, 196, 0.2);
  border-radius: 8px;
  padding: 12px;
  transition: all 0.3s ease;
  backdrop-filter: blur(5px);
}

.skill-card:hover { /*技能卡片悬停时的样式（向上平移2像素，添加阴影和边框颜色变化） 即向上移动并发光*/
  transform: translateY(-2px);
  box-shadow: 0 5px 15px rgba(78, 205, 196, 0.2);
  border-color: rgba(78, 205, 196, 0.4);
}

.clickable-skill {/* 可点击的技能卡片样式（鼠标悬停时改变背景和边框颜色）*/
  cursor: pointer;
}

.clickable-skill:hover { /* 点击时的高亮效果 可点击的技能卡片悬停时的样式（改变背景和边框颜色，向上平移2像素，添加阴影）*/
  background: rgba(78, 205, 196, 0.1);
  border-color: rgba(78, 205, 196, 0.5);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(78, 205, 196, 0.2);
}

.detail-icon { /* 详情图标样式（悬停时变红色并放大）*/
  color: #4ecdc4;
  font-size: 12px;
  cursor: pointer;
  transition: all 0.3s ease;
  margin-left: 4px;
}

.detail-icon:hover {  /* */
  color: #ff6b6b;
  transform: scale(1.1);
}

.skill-header { /* 技能卡片标题行样式（水平布局，两端对齐）*/
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 6px;
  gap: 6px;
}

.skill-header .skill-name { /* 技能卡片标题行中的技能名称样式（ flex: 1 允许名称占用剩余空间）*/
  flex: 1;
  display: flex;
  align-items: center;
  gap: 4px;
}

.skill-gif { /* 技能卡片中的GIF图片容器（居中对齐）*/
  margin: 8px 0;
  text-align: center;
  border-radius: 4px;
  overflow: hidden;
}

.skill-gif-image { /* 技能卡片中的GIF图片样式（响应式，最大宽度120px，圆角4px，边框1px透明）*/
  width: 100%;
  max-width: 120px;
  height: auto;
  border-radius: 4px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  transition: all 0.3s ease;
}

.skill-gif-image:hover {  /* 技能卡片中的GIF图片悬停时的样式（边框颜色变化，缩放1.05）*/
  border-color: rgba(78, 205, 196, 0.5);
  transform: scale(1.05);
}

.skill-name {  /* 技能卡片标题行中的技能名称样式（ flex: 1 允许名称占用剩余空间）*/
  font-size: 18px;
  font-weight: 600;
  color: #4ecdc4;
  margin: 0;
  flex: 1;
}

.skill-actions {  /* 技能卡片标题行中的操作按钮容器（水平布局，间距8px，自动换行）*/
  display: flex;
  gap: 8px;
  margin-top: 8px;
  flex-wrap: wrap;
}

.skill-detail-btn, .skill-video-btn {  /* 技能卡片标题行中的操作按钮（详情和视频按钮）样式（内边距6px 12px，圆角6px，字体大小11px，字体重量500，光标指针，过渡效果0.3s，边框1px透明）*/
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 1px solid transparent;
}

.skill-detail-btn {  /* 技能卡片标题行中的详情按钮样式（背景渐变，白色文字）*/
  background: linear-gradient(45deg, #4ecdc4, #44a08d);
  color: white;
}

.skill-detail-btn:hover {  /* 技能卡片标题行中的详情按钮悬停时的样式（向上平移2像素，添加阴影和边框颜色变化）*/
  transform: translateY(-1px);
  box-shadow: 0 3px 10px rgba(78, 205, 196, 0.3);
  background: linear-gradient(45deg, #44a08d, #4ecdc4);
}

.skill-video-btn {  /* 技能卡片标题行中的视频按钮样式（背景渐变，白色文字）*/
  background: linear-gradient(45deg, #ff6b6b, #ee5a52);
  color: white;
}

.skill-video-btn:hover {  /* 技能卡片标题行中的视频按钮悬停时的样式（向上平移2像素，添加阴影和边框颜色变化）*/
  transform: translateY(-1px);
  box-shadow: 0 3px 10px rgba(255, 107, 107, 0.3);
  background: linear-gradient(45deg, #ee5a52, #ff6b6b);
}

.detail-btn-icon, .video-btn-icon {  /* 技能卡片标题行中的操作按钮中的图标样式（字体大小9px）*/
  font-size: 9px;
}

.skill-description {  /* 技能卡片中的描述文本样式（白色，行高1.4）*/
  color: rgba(255, 255, 255, 0.8);
  line-height: 1.4;
}

.skill-description p {  /* 技能卡片中的描述文本段落样式（白色，行高1.4，字体大小15px，超出部分隐藏并显示省略号）*/
  margin: 0;
  font-size: 15px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.no-skills {   /* 无技能数据时的提示样式（居中对齐，内边距20px，颜色为rgba(255, 255, 255, 0.6)，字体样式为斜体）*/
  text-align: center;
  padding: 20px;
  color: rgba(255, 255, 255, 0.6);
  font-style: italic;
}

.no-skills p {  /* 无技能数据时的提示样式中的段落样式（白色，字体大小12px，居中对齐）*/
  margin: 0;
  font-size: 12px;
  text-align: center;
}






/* 推荐武器区域样式 - 武器展示区域的整体容器 */
.recommended-weapons {
  margin-top: 30px; /* 推荐武器区域 顶部外边距：30px */
  padding: 25px; /* 推荐武器区域 内边距：25px */
  background: rgba(255, 255, 255, 0.05); /* 推荐武器区域 背景：半透明白色 */
  border-radius: 15px; /* 推荐武器区域 圆角：15px */
  backdrop-filter: blur(10px); /* 推荐武器区域 背景模糊：10px */
  border: 1px solid rgba(255, 255, 255, 0.1); /* 推荐武器区域 边框：半透明白色1px */
}

.weapons-header {
  display: flex; /* 武器头部 布局：弹性布局 */
  align-items: center; /* 武器头部 垂直对齐：居中 */
  gap: 10px; /* 武器头部 间距：10px */
  margin-bottom: 20px; /* 武器头部 底部外边距：20px */
  padding-bottom: 15px; /* 武器头部 底部内边距：15px */
  border-bottom: 1px solid rgba(255, 255, 255, 0.1); /* 武器头部 底部边框：半透明白色1px */
}

.weapons-title {
  font-size: 1.4rem; /* 武器标题 字体大小：1.4rem */
  font-weight: 600; /* 武器标题 字体粗细：600 */
  color: #4ecdc4; /* 武器标题 颜色：青色 */
  margin: 0; /* 武器标题 外边距：0 */
}

.weapons-icon {
  font-size: 1.2rem; /* 武器图标 字体大小：1.2rem */
  color: #4ecdc4; /* 武器图标 颜色：青色 */
}

.weapons-grid {
  display: grid; /* 武器网格 布局：网格布局 */
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); /* 武器网格 网格列：自动填充最小200px */
  gap: 15px; /* 武器网格 间距：15px */
}

.weapon-card {
  background: rgba(255, 255, 255, 0.08); /* 武器卡片 背景：半透明白色 */
  border-radius: 12px; /* 武器卡片 圆角：12px */
  padding: 15px; /* 武器卡片 内边距：15px */
  cursor: pointer; /* 武器卡片 光标：指针 */
  transition: all 0.3s ease; /* 武器卡片 过渡：所有属性0.3秒 */
  border: 1px solid rgba(255, 255, 255, 0.1); /* 武器卡片 边框：半透明白色1px */
  position: relative; /* 武器卡片 定位：相对定位 */
  overflow: hidden; /* 武器卡片 溢出：隐藏 */
}

.weapon-card:hover {
  transform: translateY(-3px); /* 武器卡片悬停 变换：向上移动3px */
  background: rgba(255, 255, 255, 0.12); /* 武器卡片悬停 背景：更亮的半透明白色 */
  box-shadow: 0 8px 25px rgba(78, 205, 196, 0.2); /* 武器卡片悬停 阴影：青色阴影 */
  border-color: rgba(78, 205, 196, 0.3); /* 武器卡片悬停 边框颜色：半透明青色 */
}

.weapon-card::before {
  content: ''; /* 武器卡片伪元素 内容：空 */
  position: absolute; /* 武器卡片伪元素 定位：绝对定位 */
  top: 0; /* 武器卡片伪元素 顶部：0 */
  left: 0; /* 武器卡片伪元素 左侧：0 */
  right: 0; /* 武器卡片伪元素 右侧：0 */
  height: 3px; /* 武器卡片伪元素 高度：3px */
  background: linear-gradient(90deg, #4ecdc4, #44a08d); /* 武器卡片伪元素 背景：青色渐变 */
  opacity: 0; /* 武器卡片伪元素 透明度：0 */
  transition: opacity 0.3s ease; /* 武器卡片伪元素 过渡：透明度0.3秒 */
}

.weapon-card:hover::before {
  opacity: 1; /* 武器卡片悬停伪元素 透明度：1 */
}

.weapon-image {
  width: 100%; /* 武器图片容器 宽度：100% */
  height: 120px; /* 武器图片容器 高度：120px */
  border-radius: 8px; /* 武器图片容器 圆角：8px */
  overflow: hidden; /* 武器图片容器 溢出：隐藏 */
  margin-bottom: 12px; /* 武器图片容器 底部外边距：12px */
  background: rgba(0, 0, 0, 0.2); /* 武器图片容器 背景：半透明黑色 */
}

.weapon-image img {
  width: 100%; /* 武器图片 宽度：100% */
  height: 100%; /* 武器图片 高度：100% */
  object-fit: cover; /* 武器图片 对象适应：覆盖 */
  transition: transform 0.3s ease; /* 武器图片 过渡：变换0.3秒 */
}

.weapon-card:hover .weapon-image img {
  transform: scale(1.05); /* 武器卡片悬停时图片 变换：放大1.05倍 */
}

.weapon-name {
  font-size: 1rem; /* 武器名称 字体大小：1rem */
  font-weight: 600; /* 武器名称 字体粗细：600 */
  color: white; /* 武器名称 颜色：白色 */
  margin: 0 0 8px 0; /* 武器名称 外边距：底部8px */
  line-height: 1.3; /* 武器名称 行高：1.3 */
}

.weapon-type {
  font-size: 0.85rem; /* 武器类型 字体大小：0.85rem */
  color: rgba(255, 255, 255, 0.7); /* 武器类型 颜色：半透明白色 */
  margin: 0; /* 武器类型 外边距：0 */
  padding: 4px 8px; /* 武器类型 内边距：4px 8px */
  background: rgba(78, 205, 196, 0.2); /* 武器类型 背景：半透明青色 */
  border-radius: 12px; /* 武器类型 圆角：12px */
  display: inline-block; /* 武器类型 显示：内联块 */
}

.weapons-loading {
  text-align: center; /* 武器加载状态 文本对齐：居中 */
  padding: 40px 20px; /* 武器加载状态 内边距：40px 20px */
  color: rgba(255, 255, 255, 0.6); /* 武器加载状态 颜色：半透明白色 */
}

.loading-spinner {
  width: 50px; /* 加载旋转器重复 宽度：50px */
  height: 50px; /* 加载旋转器重复 高度：50px */
  border: 4px solid rgba(255, 255, 255, 0.3); /* 加载旋转器重复 边框：半透明白色4px */
  border-top: 4px solid #ff6b6b; /* 加载旋转器重复 顶部边框：红色4px */
  border-radius: 50%; /* 加载旋转器重复 圆角：50% */
  animation: spin 1s linear infinite; /* 加载旋转器重复 动画：旋转1秒线性无限 */
  margin-bottom: 20px; /* 加载旋转器重复 底部外边距：20px */
}

@keyframes spin {
  0% { transform: rotate(0deg); } /* 旋转动画重复 0%：旋转0度 */
  100% { transform: rotate(360deg); } /* 旋转动画重复 100%：旋转360度 */
}

.no-weapons {
  text-align: center; /* 无武器状态 文本对齐：居中 */
  padding: 40px 20px; /* 无武器状态 内边距：40px 20px */
  color: rgba(255, 255, 255, 0.6); /* 无武器状态 颜色：半透明白色 */
}

.no-weapons-icon {
  font-size: 3rem; /* 无武器图标 字体大小：3rem */
  margin-bottom: 15px; /* 无武器图标 底部外边距：15px */
  opacity: 0.5; /* 无武器图标 透明度：0.5 */
}

.no-weapons p {
  margin: 0; /* 无武器文本 外边距：0 */
  font-size: 1rem; /* 无武器文本 字体大小：1rem */
  font-style: italic; /* 无武器文本 字体样式：斜体 */
}

/* 导航箭头样式 - 图片轮播导航控制 */
.nav-arrow {
  position: absolute; /* 导航箭头重复 定位：绝对定位 */
  top: 50%; /* 导航箭头重复 顶部：50% */
  transform: translateY(-50%); /* 导航箭头重复 变换：垂直居中 */
  width: 40px; /* 导航箭头重复 宽度：40px */
  height: 40px; /* 导航箭头重复 高度：40px */
  background: rgba(255, 255, 255, 0.2); /* 导航箭头重复 背景：半透明白色 */
  border-radius: 50%; /* 导航箭头重复 圆角：50% */
  display: flex; /* 导航箭头重复 布局：弹性布局 */
  align-items: center; /* 导航箭头重复 垂直对齐：居中 */
  justify-content: center; /* 导航箭头重复 水平对齐：居中 */
  cursor: pointer; /* 导航箭头重复 光标：指针 */
  transition: all 0.3s ease; /* 导航箭头重复 过渡：所有属性0.3秒 */
  z-index: 10; /* 导航箭头重复 层级：10 */
}

.nav-arrow:hover {
  background: rgba(255, 255, 255, 0.3); /* 导航箭头悬停重复 背景：更亮的半透明白色 */
}

.nav-arrow-right {
  right: 10px; /* 右导航箭头重复 右侧：10px */
}

.nav-arrow span {
  font-size: 1.5rem; /* 导航箭头图标重复 字体大小：1.5rem */
  color: white; /* 导航箭头图标重复 颜色：白色 */
}


/* 加载和错误状态样式 - 重复定义样式 */
.loading-container,
.error-container {
  display: flex; /* 加载/错误容器重复 布局：弹性布局 */
  flex-direction: column; /* 加载/错误容器重复 弹性方向：列 */
  align-items: center; /* 加载/错误容器重复 水平对齐：居中 */
  justify-content: center; /* 加载/错误容器重复 垂直对齐：居中 */
  min-height: 400px; /* 加载/错误容器重复 最小高度：400px */
  text-align: center; /* 加载/错误容器重复 文本对齐：居中 */
}

.retry-btn {
  padding: 10px 20px; /* 重试按钮重复 内边距：10px 20px */
  background: #ff6b6b; /* 重试按钮重复 背景：红色 */
  color: white; /* 重试按钮重复 文字颜色：白色 */
  border: none; /* 重试按钮重复 边框：无 */
  border-radius: 5px; /* 重试按钮重复 圆角：5px */
  cursor: pointer; /* 重试按钮重复 光标：指针 */
  margin-top: 10px; /* 重试按钮重复 顶部外边距：10px */
  transition: background 0.3s ease; /* 重试按钮重复 过渡：背景0.3秒 */
}

.retry-btn:hover {
  background: #ff5252; /* 重试按钮悬停重复 背景：更深的红色 */
}

/* 响应式设计 - 不同屏幕尺寸适配 */
@media (max-width: 1100px) {
  .valkyrie-layout { 
    grid-template-columns: 220px 1fr 360px; /* 中等屏幕 三栏布局 网格列：左侧220px 中间自适应 右侧360px */
  }
}

@media (max-width: 900px) {
  .valkyrie-layout { 
    grid-template-columns: 1fr; /* 小屏幕 三栏布局 网格列：单列自适应 */
    min-height: auto; /* 小屏幕 三栏布局 最小高度：自动 */
  }
  .valkyrie-right { 
    order: 2; /* 小屏幕 右侧栏 顺序：2 */
  }
  .thumb-strip { 
    justify-content: center; /* 小屏幕 缩略图条 水平对齐：居中 */
  }
  .valkyrie-left { 
    order: 3; /* 小屏幕 左侧栏 顺序：3 */
  }
}

@media (max-width: 768px) {
  .hero-main-display {
    flex-direction: column; /* 移动端重复 英雄主展示 弹性方向：列布局 */
    text-align: center; /* 移动端重复 英雄主展示 文本对齐：居中 */
  }
  
  .hero-main-image {
    width: 300px; /* 移动端重复 英雄主图 宽度：300px */
    height: 400px; /* 移动端重复 英雄主图 高度：400px */
  }
  
  .hero-name {
    font-size: 2rem; /* 移动端重复 英雄名称 字体大小：2rem */
  }
  
  .page-title {
    font-size: 2rem; /* 移动端重复 页面标题 字体大小：2rem */
  }
  
  .skills-list {
    grid-template-columns: 1fr; /* 移动端 技能列表 网格列：单列 */
    gap: 15px; /* 移动端 技能列表 间距：15px */
  }
  
  .skill-header {
    flex-direction: column; /* 移动端 技能头部 弹性方向：列 */
    align-items: flex-start; /* 移动端 技能头部 对齐：左对齐 */
    gap: 10px; /* 移动端 技能头部 间距：10px */
  }
  
  .skills-section {
    padding: 0 15px; /* 移动端 技能区域 内边距：0 15px */
  }
  
  .weapons-grid {
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); /* 移动端 武器网格 网格列：自动填充最小150px */
    gap: 12px; /* 移动端 武器网格 间距：12px */
  }
  
  .weapon-card {
    padding: 12px; /* 移动端 武器卡片 内边距：12px */
  }
  
  .weapon-image {
    height: 100px; /* 移动端 武器图片 高度：100px */
  }
  
  .weapons-title {
    font-size: 1.2rem; /* 移动端 武器标题 字体大小：1.2rem */
  }
}
</style>